﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using Intorise.Common;
using Config;

namespace Model
{
    public partial class Player
    {
        #region Processor
        public void InitProcessor()
        {
            if (Initialized) { return; }
            Initialized = true;
            engine.RegisterProcessor(new Processor("ProcessAttackMonster", MessageTypeEnum.Attack, ProcessAttackMonster));
            engine.RegisterProcessor(new Processor("ProcessServerResult", MessageTypeEnum.ServerResult, ProcessServerResult));
            engine.RegisterProcessor(new Processor("ProcessMapEntered", MessageTypeEnum.MapEntered, ProcessMapEntered));
            engine.RegisterProcessor(new Processor("ProcessLocationChanged", MessageTypeEnum.LocationChanged, ProcessLocationChanged));
            engine.RegisterProcessor(new Processor("ProcessPlayerMoved", MessageTypeEnum.PlayerMoved, ProcessPlayerMoved));
            engine.RegisterProcessor(new Processor("ProcessHP", MessageTypeEnum.HeathPointChanged, ProcessHP));
            engine.RegisterProcessor(new Processor("ProcessUnderAttack", MessageTypeEnum.UnderAttack, ProcessUnderAttack));
            engine.RegisterProcessor(new Processor("ProcessMpChanged", MessageTypeEnum.MpChanged, ProcessMpChanged));
            engine.RegisterProcessor(new Processor("ProcessHpChanged", MessageTypeEnum.HpChanged, ProcessHpChanged));
            engine.RegisterProcessor(new Processor("ProcessGoldChanged", MessageTypeEnum.GoldChanged, ProcessGoldChanged));
            engine.RegisterProcessor(new Processor("ProcessItemBuy", MessageTypeEnum.ItemGeted, ProcessItemBuy));
            engine.RegisterProcessor(new Processor("ProcessItemBuy0", MessageTypeEnum.ItemGeted0, ProcessItemBuy));
            engine.RegisterProcessor(new Processor("ProcessItemDroped", MessageTypeEnum.ItemDroped, ProcessItemDroped));
            engine.RegisterProcessor(new Processor("ProcessItemPickuped", MessageTypeEnum.ItemPickuped, ProcessItemPickuped));
            engine.RegisterProcessor(new Processor("ProcessRide", MessageTypeEnum.Ride, ProcessRide));
            engine.RegisterProcessor(new Processor("ProcessSignCount", MessageTypeEnum.SignCount, ProcessSignCount));
            engine.RegisterProcessor(new Processor("ProcessLevelUp", MessageTypeEnum.LevelUp, ProcessLevelUp));

            engine.RegisterProcessor(new Processor("ProcessInviteTrade", MessageTypeEnum.InviteTrade, ProcessInviteTrade));
            engine.RegisterProcessor(new Processor("ProcessAgreeTrade", MessageTypeEnum.AgreeTrade, ProcessAgreeTrade));
            engine.RegisterProcessor(new Processor("ProcessLockTrade", MessageTypeEnum.LockTrade, ProcessLockTrade));
            //engine.RegisterProcessor(new Processor("ProcessAffirmTrade", MessageTypeEnum.AffirmTrade, ProcessAffirmTrade));
        }

        public bool ProcessUnderAttack(Message x)
        {
            GameHelper.Run(x, r =>
            {
                var msg = new UnderAttackMsg(x.Data);
                if (msg.AttackerID == this.ID)//攻击怪物
                {
                    if (logDebugInfo) { ConsoleBLL.WriteLine(string.Format("UnderAttack：{0} 攻击怪物，伤害{1}，当前血量{2}", this, msg.Damage, msg.CurrentHP)); }

                    if (msg.CurrentHP <= 0)//杀死怪物
                    {
                        var monster = engine.GetMonster(msg.TargetID);
                        if (monster != null)
                        {
                            monster.Alive = false;
                        }
                        KilledCount++;
                        if (logDebugInfo) ConsoleBLL.WriteLine(msg.TargetID.ToString("X2") + "怪物已死亡");
                    }
                }
                else if (msg.TargetID == this.ID)
                {
                    if (logDebugInfo) { ConsoleBLL.WriteLine(string.Format("UnderAttack：{0}被怪物{1} 攻击，伤害{2}，当前血量{3}", this, msg.AttackerID.ToString("X2"), msg.Damage, msg.CurrentHP)); }
                    TreatHP(msg.CurrentHP);
                    if (this.Status == PlayerStatusEnum.自动打怪)
                    {
                        engine.Found(new Monster { InstanceID = msg.AttackerID, Location = this.Location });
                    }
                }
            });
            return true;
        }

        public bool ProcessAttackMonster(Message x)
        {
            GameHelper.Run(x, r =>
            {
                var msg = new AttackMsg(x.Data);
                if (msg.AttackerID == this.ID)//攻击怪物
                {
                    if (logDebugInfo) { ConsoleBLL.WriteLine(string.Format("AttackMonster：{0} 攻击怪物，伤害{1}，当前血量{2}", this, msg.Damage, msg.CurrentHP)); }

                    if (msg.CurrentHP <= 0)//杀死怪物
                    {
                        var monster = engine.GetMonster(msg.TargetID);
                        if (monster != null)
                        {
                            monster.Alive = false;
                        }
                        KilledCount++;
                        if (logDebugInfo) ConsoleBLL.WriteLine(msg.TargetID.ToString("X2") + "怪物已死亡");
                    }
                }
                else if (msg.TargetID == this.ID)
                {
                    //if (logDebugInfo) { ConsoleBLL.WriteLine(string.Format("AttackMonster：{0}被怪物{1} 攻击，伤害{2}，当前血量{3}", this, msg.AttackerID.ToString("X2"), msg.Damage, msg.CurrentHP)); }
                    //TreatHP(msg.CurrentHP);
                    //if (this.Status == PlayerStatusEnum.自动打怪)
                    //{
                    //    engine.Found(new Monster { InstanceID = msg.AttackerID, Location = this.Location });
                    //}
                    //else if (this.Status != PlayerStatusEnum.前往挂机地点)
                    //{
                    //    //var monster = new Monster { InstanceID = msg.KillerID };
                    //    //Thread thread = new Thread(new ParameterizedThreadStart(y =>
                    //    //{
                    //    //    while (monster.Alive)
                    //    //    {
                    //    //        skillList.ForEach(f => { KillMonster(f, monster); });
                    //    //    }
                    //    //}));
                    //    //thread.Start();
                    //}
                    ////ConsoleBLL.WriteLine(this + " " + msg.KillerID + "攻击" + msg.TheKilled + "，伤害：" + msg.Damage);
                }

            });
            return true;
        }

        public bool ProcessServerResult(Message x)
        {
            GameHelper.Run(x, r =>
            {
                var msg = new ResultMsg(x.Data);


                if (msg.ResultText.Contains("恭喜您获得"))//购买返回
                {
                    //ProcessItemGot(msg);
                }
                else if (msg.ResultText.Contains("拾取的物品太远"))
                {
                    ((BotConfig)ConfigManager.BusinessConfig).GetItemDistance = 0;
                }
                if (msg.ResultText.Contains("包裹位置不足"))
                {
                    ConsoleBLL.WriteLineError(this.ToString() + " " + msg.ResultText);
                    this.Status = PlayerStatusEnum.包裹已满;
                }
                else if (msg.ResultText.Contains("死亡状态下") || msg.ResultText.Contains("您已经死亡") || msg.ResultText.Contains("您被怪物【{1}】击败了"))
                {
                    Revive();
                    return;
                    ConsoleBLL.WriteLineError(this.ToString() + " " + msg.ResultText);
                    this.Quit();
                }
                else if (msg.ResultText.Contains("捡到"))
                {
                    #region 捡到
                    PickupItemMsg item = new PickupItemMsg(msg.Data);
                    ConsoleBLL.WriteLineWaring(this.ToString() + " " + msg.ResultText);
                    lock (Items)
                    {
                        var lastItem = Items.LastOrDefault();
                        if (lastItem != null && lastItem.Name == "未知物品")
                        {
                            lastItem.Name = item.Name;
                        }
                        if (lastItem != null && IsNeedSell(lastItem.Name))
                        {
                            Sell(lastItem);
                            Items.Remove(lastItem);
                        }
                        var list = Items.GroupBy(g => g.Name).ToList();
                        SumItems(list);
                    }

                    lock (medicinals)
                    {
                        if (medicinals.Count > 3)
                        {
                            medicinals.ForEach(m =>
                            {
                                Sell(m);
                                medicinals.Remove(m);
                            });
                        }
                    }
                    #endregion
                }
                else if (msg.ResultText.Contains("魔法值不足"))
                {
                    PauseAutoFight = true;
                    for (int i = 0; i < 5; i++)
                    {
                        Treat(Thing.MedicinalType.MP0);
                        Thread.Sleep(5000);
                    }
                    PauseAutoFight = false;
                }
                else if (msg.ResultText.Contains("经验"))
                {
                    string expString = Tools.SubString(msg.ResultText, ">", "<", true);
                    if (expString == "")
                    {
                        expString = Tools.SubString(msg.ResultText, "........", "....", true);
                    }
                    //获得{1}{2}经验........21074....
                    int exp = 0;
                    int.TryParse(expString, out exp);
                    Exp += exp;
                    ExpRange = Math.Round((double)Exp / (DateTime.Now - startAutoFightTime).TotalMinutes / 10000, 2);
                }
                else if (msg.ResultText.Contains("目标线路未找到"))
                {
                    ConsoleBLL.WriteLineWaring(this + " " + msg.ResultText);
                    Change(new Random().Next(3) + 1);
                }
                else if (logServerInfo)
                {
                    ConsoleBLL.WriteLine(this.ToString() + " " + msg.ResultText);
                }
            });
            return true;
        }

        public bool ProcessMapEntered(Message x)
        {
            GameHelper.Run(x, r =>
            {
                var item = new MapEnteredMsg(x.Data);
                this.Location = item.Location;
                this.X = item.X;
                this.Y = item.Y;
                this.Line = item.Line;
                ConsoleBLL.WriteLineInfo(this + " 进入地图，当前坐标：" + item.Location);
            });
            return true;
        }

        public bool ProcessLocationChanged(Message x)
        {
            GameHelper.Run(x, r =>
            {
                var item = new LocationChangedMsg(x.Data);
                if (this.ID == item.UserID)
                {
                    this.Location = item.Location;
                    this.X = item.X;
                    this.Y = item.Y;
                    if (logDebugInfo) ConsoleBLL.WriteLineInfo(this + " 当前坐标：" + item.Location);
                }
            });
            return true;
        }

        public bool ProcessPlayerMoved(Message x)
        {
            GameHelper.Run(x, r =>
            {
                var item = new PlayerMovedMsg(x.Data);
                if (item.MoverID == this.ID)
                {
                    if (logDebugInfo) ConsoleBLL.WriteLineInfo("从" + item.Location + "移动到" + Tools.GetHexString(item.MoveData, item.MoveData.Length));
                }
                else
                {
                    //ConsoleBLL.WriteLineInfo(item.MoverID.ToString("X2") + "从" + item.Location + "移动" + Tools.GetHexString(item.MoveData, item.MoveData.Length));
                }
            });
            return true;
        }

        public bool ProcessHP(Message x)
        {
            GameHelper.Run(x, r =>
            {
                var item = new HeathPointChangedMsg(x.Data);
                if (item.OwnerID == this.ID)
                {
                    TreatHP(item.CurrentHP);
                    if (logDebugInfo) ConsoleBLL.WriteLineInfo(this + string.Format(" 血量：{1}/{2}", item.OwnerID.ToString("X2"), item.CurrentHP, item.TotalHP));
                }
                else
                {
                    //ConsoleBLL.WriteLineInfo(string.Format("{0}血量：{1}/{2}", item.OwnerID.ToString("X2"), item.CurrentHP, item.TotalHP));
                }
            });
            return true;
        }

        public bool ProcessMpChanged(Message x)
        {
            GameHelper.Run(x, r =>
            {
                var item = new MpChangedMsg(x.Data);
                if (item.ID == this.ID)
                {
                    this.CurrentMP = item.CurrentMP;
                    if (TotalMP < CurrentMP) { TotalMP = CurrentMP; }
                    double mpRange = (double)this.CurrentMP / TotalMP;
                    if (mpRange <= (double)Config.MP2 / 100)
                    {
                        Treat(Thing.MedicinalType.MP2);
                    }
                    else if (mpRange <= (double)Config.MP1 / 100)
                    {
                        if (medicinals.Count(w => w.Type == 6) == 0)//没有大蓝在买
                        {
                            Treat(Thing.MedicinalType.MP1);
                        }
                    }
                    else if (mpRange <= (double)Config.MP0 / 100)
                    {
                        lock (medicinals)
                        {
                            if (medicinals.Count(w => w.Type == 4) == 0 || medicinals.Count(w => w.Type == 6) == 0)//没有大蓝和中蓝在买
                            {
                                Treat(Thing.MedicinalType.MP0);
                            }
                        }
                    }
                }
                else
                {

                }
            });
            return true;
        }

        public bool ProcessHpChanged(Message x)
        {
            GameHelper.Run(x, r =>
            {
                var item = new HpChangedMsg(x.Data);
                if (item.ID == this.ID)
                {
                    //ConsoleBLL.WriteLineInfo(string.Format("HP：{0}/{1}", item.CurrentHP, TotalHP));
                    TreatHP(item.CurrentHP);
                }
                else
                {

                }
            });
            return true;
        }

        public bool ProcessGoldChanged(Message x)
        {
            GameHelper.Run(x, r =>
            {
                var item = new GoldChangedMsg(x.Data);
                this.TotalGold = item.GoldCount;
                //ConsoleBLL.WriteLineInfo(string.Format("Gold：{0}", item.GoldCount));
            });
            return true;
        }

        //购物返回
        public bool ProcessItemBuy(Message x)
        {
            GameHelper.Run(x, r =>
            {
                var item = new ItemGetedMsg(x.Data);
                if (item.Item != null)
                {
                    if (item.Item.Name.Contains("药包"))
                    {
                        UseItem(item.Item);
                    }
                    else if (item.Item.Name.Contains("之翼"))
                    {
                        EquipItem(item.Item);
                    }
                    else if (item.Item is Medicinal)
                    {
                        lock (medicinals)
                        {
                            if (medicinals.Count(c => c.InstanceID == item.Item.InstanceID) == 0)
                            {
                                medicinals.Add((Medicinal)item.Item);
                            }
                        }
                    }
                    lock (lastBuyMedicinals)
                    {
                        var medicinal = lastBuyMedicinals.FirstOrDefault(w => w.Name == item.Item.Name);
                        if (medicinal != null)
                        {
                            lastBuyMedicinals.Remove(medicinal);
                        }
                    }
                    if (logDebugInfo) ConsoleBLL.WriteLineInfo(this + string.Format(" 获得物品{0}", item.Item.Name));
                }
                else
                {
                    if (logDebugInfo) ConsoleBLL.WriteLineError(this + " 获得未知物品：" + item.Type);
                }
            });
            return true;
        }

        public bool ProcessItemDroped(Message x)
        {
            GameHelper.Run(x, r =>
            {
                var item = new ItemDropedMsg(x.Data);

                if (item.OwnerID == this.ID)
                {
                    if (logDebugInfo) ConsoleBLL.WriteLineInfo(this + " 掉落物品：" + item.DropedItem.Name + "(" + item.DropedItem.ID.ToString("X") + ")");
                    if (Config.OnlyPickupSpecify && this.needGetTiems.Count(w => item.DropedItem.Name.Contains(w)) > 0)
                    {
                        GetItem(item);
                    }
                    else if (dontPickupTiems.Count(w => item.DropedItem.Name.Contains(w)) == 0)
                    {
                        GetItem(item);
                    }
                }
            });
            return true;
        }

        public bool ProcessRide(Message x)
        {
            var item = new RideMsg(x.Data);
            if (item.PlayerID == this.ID)
            {
                if (logDebugInfo)
                {
                    if (item.IsRide)
                    {
                        ConsoleBLL.WriteLine(this + " 上马");
                    }
                    else
                    {
                        ConsoleBLL.WriteLine(this + " 下马");
                    }
                }
                this.IsRide = item.IsRide;
            }
            return true;
        }

        //拾到物品
        public bool ProcessItemPickuped(Message x)
        {
            GameHelper.Run(x, r =>
            {
                lock (Items)
                {
                    var item = new ItemPickupedMsg(x.Data);

                    if (item.GetedItem.Name == "卓越装备" && Config.AutoTL)
                    {
                        TiLian(item.GetedItem);
                    }
                    else if (item.GetedItem is Medicinal)//药品
                    {
                        lock (medicinals)
                        {
                            if (medicinals.Count(c => c.InstanceID == item.GetedItem.InstanceID) == 0)
                            {
                                medicinals.Add((Medicinal)item.GetedItem);
                            }
                        }
                    }
                    else
                    {
                        if (item.GetedItem.Name == "金币") { return; }
                        Items.Add(item.GetedItem);
                        if (this.ID != Player.Master.ID)
                        {
                            lock (queue)
                            {
                                if (queue.Count(w => w.ID == this.ID) == 0)//需要交易
                                {
                                    queue.Add(this);
                                }
                            }
                        }
                    }
                    lock (lastBuyMedicinals)
                    {
                        var medicinal = lastBuyMedicinals.FirstOrDefault(f => f.Name == item.GetedItem.Name);
                        if (medicinal != null)
                        {
                            lastBuyMedicinals.Remove(medicinal);
                        }
                    }
                }
            });
            return true;
        }

        //签到次数
        public bool ProcessSignCount(Message x)
        {
            GameHelper.Run(x, r =>
            {
                var item = new SignCountMsg(x.Data);
                ConsoleBLL.WriteLine(this + " 已签到次数：" + item.Count);
            });
            return true;
        }

        public bool ProcessLevelUp(Message x)
        {
            GameHelper.Run(x, r =>
            {
                var item = new LevelUpMsg(x.Data);
                ConsoleBLL.WriteLine(this + " 已升级，当前等级：" + item.Level + "，自动加点1力量4敏捷");
                this.engine.SendData(DataPackager.GetAddPointData());
            });
            return true;
        }
        #endregion
    }
}
